//	--------------------------------------------------------------------
//	Copyright(C) 2006,2007 Zhao Yukun. All rights reserved.
//	This file is a part of the Xeres system.
//	Xeres 2007
//	Contact : xeres.engine@gmail.com
//	$(reservedInfo)
//	$(reservedDeclaration)
//	--------------------------------------------------------------------
///	@file	<updater.h>
///	@path	~/src/gui/
///	@date	2008/06/03
///	@desc	.

#pragma once

#include "xeres.h"

#include "lib/utilities/string.h"
#include "lib/math/rect.h"
#include "lib/math/pair.h"

#include "object/object_ref.h"

#include "gui/input/input.h"

#include <vector>

namespace xeres {

	// forward declaration
	class IGuiComp;
	class IGuiForm;
	class Updater;

	/*! 
		\class	UpdateGuard
		\brief	Update context guard.
	*/
	class UpdateGuard
	{
	public:

		/// \ctor
		UpdateGuard( RefWeak<IGuiForm> form , Updater& updater , const Pair<int>& base );

		/// \dtor
		~UpdateGuard( void );

	private:

		friend class Updater;

		//@ data
		RefWeak<IGuiForm>	m_form;
		UpdateGuard *		m_lastGuard;
		Updater&			m_updater;
		Pair<int>			m_base;
	};

	/*! 
		\class	Updater
		\brief	Update context of GUI components.
	*/
	class Updater : public InputMsg
	{
	public:

		/// \ctor
		Updater( RefWeak<IGuiForm> root )
			: m_root( root )
			, m_guard( NULL )
		{
		}

		/// \ctor
		Updater( RefWeak<IGuiForm> root , const InputMsg& input )
			: InputMsg( input )
			, m_root( root )
			, m_guard( NULL )
		{
		}

		/// \ctor
		Updater( RefWeak<IGuiForm> root , const KeyInput& input )
			: InputMsg( input )
			, m_root( root )
			, m_guard( NULL )
		{
		}

		/// \ctor
		Updater( RefWeak<IGuiForm> root , const MouseInput& input )
			: InputMsg( input )
			, m_root( root )
			, m_guard( NULL )
		{
		}

		/// \dtor
		~Updater( void )
		{
		}

		/// \name	Update Methods.
		//@{

		/// \brief	Reset local point
		void ResetPoint( void ) {
			if( GetInput().IsMouseInput() )
			{
				m_localPt = GetMouseInput().GetPoint();
			}
		}

		/// \brief	Get local point.
		Pair<int> GetPoint( void ) const {
			assert( GetInput().IsMouseInput() ); return m_localPt;
		}

		/// \brief	Add dirty region.
// 		void PolluteRegion( RefWeak<IGuiForm> base , const Rect<int>& region );
// 
// 		/// \brief	Add polluted region.
// 		const Rect<int>& GetPolluted( void ) const { return m_dirtRect; }
// 
// 		/// \brief	Determine if update is needed.
// 		bool NeedsUpdate( void ) const { return !m_dirtRect.is_empty(); }

		//@}

	private:

		friend class UpdateGuard;
		
		//@ data

		// local point
		Pair<int>			m_localPt;

		// current update guard
		UpdateGuard *		m_guard;

		// dirt region
//		Rect<int>			m_dirtRect;

		// root form
		RefWeak<IGuiForm> 	m_root;
	};

} // namespace xeres
